// Filename: 64TO_MPH.CPP

/************   Complex to real picture converter  ********************\

1993 (c) CDI UI, The USSR Academy of Sciences, Samara
Two functoins: 
  _64to_mod: complex -> module
  _64to_ph : complex -> phase
            
\**********************************************************************/
#include <io.h>
#include <dos.h>
#include <string.h>
#include <stdio.h>
#include "fft.h"
#include "indicat.h"
#define MODULE 1
#define PHASE  2

int _64to_mod( char *ComplexPic, char *DstPic ){
  return _64to_mph( ComplexPic, DstPic, MODULE );
}

int _64to_ph( char *ComplexPic, char *DstPic ){
  return _64to_mph( ComplexPic, DstPic, PHASE );
}

int _64to_mph( char *ComplexPic, char *DstPic, int Mode ){
char *dob[] =
  { "ComplToModule{}", "ComplToPhase{}" };
char maxmin[35];
float amin,amax;

if(Mode!=MODULE && Mode!=PHASE) return InvalidParams;
int fsrc = open(ComplexPic,1);
if ( fsrc == -1 ) return NoFile;
int head[4]; _read(fsrc,head,8);
if(head[2]!=64) return WrongType;
int m=head[0], n=head[1], cl0=head[3];
if( (long)m*n*8+8+head[3] != filelength(fsrc) ) return InvalidPicture;
dfree freespace; getdfree(0,&freespace);

long fsp   = (long)freespace.df_avail*freespace.df_bsec*freespace.df_sclus;
long reqsp = (long)m*n*4+8+head[3]+30;
if(fsp < reqsp) return NoDiskSpace;
char *comm = new char[head[3]+55];
float *sf = new float[n];
Complex *str_src = new Complex[n];
if ( !str_src) return NoMemory;

head[2]=32;
int cl;
switch(Mode){
  case MODULE: cl=strlen(dob[0]); break;
  case PHASE : cl=strlen(dob[1]); break;
}
int fdest = open(DstPic, 770, 128 );
head[3]+=cl; _write(fdest,head,8);

check_indicator Ind(m,"Complex-module conversion");
int i; float val;
if (Mode==MODULE) {
  amax=-1.0; amin=1.0E+20;
  for(i=0;i<m;i++) {
    _read(fsrc, str_src, n*8);
    for(int j=0;j<n;j++) {
      sf[j]=val=hypot(str_src[j].re, str_src[j].im);
      if(val<amin) amin=val; if(val>amax) amax=val;
			 }
    _write( fdest, sf, 4*n);
    Ind.update(i);
    if(Ind.check()){
	close(fsrc); close(fdest); unlink(DstPic);
	delete sf; delete str_src; delete comm;
	return User_break;
    } 
  }
sprintf(maxmin,"MinMax{%e %e}",amin,amax);
}
else {
  for(i=0;i<m;i++) {
    _read(fsrc, str_src, n*8);
    for(int j=0;j<n;j++)
      if (str_src[j].re==0 && str_src[j].im==0) sf[j]=0.0;
	else sf[j]=atan2(str_src[j].im,str_src[j].re);
    _write( fdest, sf, 4*n);
    Ind.update(i);
    if(Ind.check()){
      close(fsrc); close(fdest); unlink(DstPic);
      delete sf; delete str_src; delete comm;
      return User_break;
    } 
  }
}
delete sf; delete str_src;

_read( fsrc, comm, cl0 ); close(fsrc);
comm[cl0]=0;
char *pos1, *pos2;
switch(Mode) {
  case MODULE:
    strcat(comm,dob[0]);
    pos1=strstr(comm,"MinMax{");
    if(pos1!=NULL) {
      pos2=strchr(pos1,'}');
      memmove(pos1,pos2+1,(unsigned int)(&comm[strlen(comm)]-pos2));
		   }
    strcat(comm,maxmin);
    cl=strlen(comm); head[3]=cl;
    lseek(fdest,6,SEEK_SET); _write(fdest,&head[3],2);
    lseek(fdest,8+(long)m*n*4,SEEK_SET);
    _write( fdest, comm, cl);
    break;
  case PHASE : strcat(comm,dob[1]); _write( fdest, comm, cl0+cl); break;
}

close(fdest);

delete comm;
return 0;
}

